﻿using System;
using System.Web;
using OpenPhotoAlbum.BusinessLogics;
using OpenPhotoAlbum.Controls;

namespace OpenPhotoAlbum
{
	/// <summary>
	/// The base class of all pages.
	/// </summary>
	public class AlbumPage : System.Web.UI.Page
	{
		public static readonly Guid SaltUserId = Guid.NewGuid();
		private Guid _cacheKeyUserId = Guid.Empty;

		public AlbumPage()
			: base()
		{
		}

		protected override void OnPreInit(EventArgs e)
		{
			base.OnPreInit(e);

			// Set current theme.
			this.Theme = "Classic";
		}

		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);

			// Clear existing sitmap nodes.
			this.SiteMapProvider.ClearAllNodes();
		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			// Invoke this virtual method to append sitemap nodes.
			this.AppendSiteMapNodes(this.SiteMapProvider);
		}

		protected virtual void AppendSiteMapNodes(AlbumSiteMapProvider provider)
		{
		}

		protected override void OnError(EventArgs e)
		{
			base.OnError(e);

			Exception exception = HttpContext.Current.Error;
			ActionManager.Instance.AddApplicationError(exception, RawUrl);
		}

		/// <summary>
		/// Gets the ID of current user if identified.
		/// (This property tries to get the ID from cache first,
		/// in order to prevent repeated database access.)
		/// </summary>
		protected Guid UserId
		{
			get
			{
				if (!UserManager.Instance.IsUserLoggedIn)
					return Guid.Empty;

				// 1st: get user name.
				string userName = HttpContext.Current.User.Identity.Name;

				// 2nd: get cache key.
				if (_cacheKeyUserId.Equals(Guid.Empty))
					_cacheKeyUserId = GuidUtility.Combine(userName, SaltUserId);

				// 3rd: read user id from cache and return if found.
				if (CacheManager.Instance.ContainsKey(_cacheKeyUserId))
					return CacheManager.Instance.ReadCache<Guid>(_cacheKeyUserId);

				// 4th: read user id from database.
				Guid userId = UserManager.Instance.GetUser(userName).UserId;
				CacheManager.Instance.WriteCache<Guid>(_cacheKeyUserId, userId);

				return userId;
			}
		}

		private Controls.AlbumSiteMapProvider SiteMapProvider
		{
			get
			{
				// In Web.Config, AlbumSiteMapProvider is configured
				// as the default sitemap provider.
				return (AlbumSiteMapProvider)SiteMap.Provider;
			}
		}

		protected string RawUrl
		{
			get { return Request.RawUrl; }
		}

		public static string ApplicationName
		{
			get { return System.Configuration.ConfigurationManager.AppSettings["appName"]; }
		}

		public new string Title
		{
			get { return base.Title; }
			set { base.Title = HttpUtility.HtmlEncode(value); }
		}
	}
}
